<?php
/**
 * @Notes:【】
 * @User: zwc
 * @Date: 2022-05-01 17:14
 */

namespace App\WsService;

use App\Dao\Chat\ChatFdDao;
use App\Repository\WebSocket\UsersData;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Server\ServerFactory;
use Hyperf\WebSocketServer\Sender;
use Swoole\Server;
use Swoole\WebSocket\Frame;

class SocketClientService
{

    /**
     * @Inject()
     * @var ChatFdDao
     */
    protected $chatFdDao;

    /**
     * 客户端fd与用户ID绑定关系
     *
     * @param int $fd 客户端fd
     * @param int $user_id 用户ID
     * @param string $run_id 服务运行ID（默认当前服务ID）
     */
    public function bind(int $fd, UsersData $usersData, int $types = 0)
    {
        $this->chatFdDao->create([
            'fd' => $fd,
            'server_run_id' => SERVER_RUN_ID,
            'user_id' => $usersData->getUid(),
            'types' => $usersData->getType()
        ]);
    }

    public function unbind(int $fd)
    {
        $chatFdDao = $this->chatFdDao->where('fd', $fd)->where('server_run_id', SERVER_RUN_ID)->first();
        $chatFdDao->delete();
        return $chatFdDao;
    }

    public function exists(int $fd)
    {
//        Sender::class
//        $pingFrame = new Frame();
//        $pingFrame->opcode = WEBSOCKET_OPCODE_PING;
//        $server->push($fd, $pingFrame)
    }

    public function getFds($user_id, $types)
    {
        return $this->chatFdDao
            ->where('server_run_id', SERVER_RUN_ID)
            ->where('user_id', $user_id)
            ->where('types', $types)
            ->pluck('fd');
    }

    public function sendUserMessageV1($userId, string $event, $data = [], $types = 1)
    {
        $fds = $this->getFds($userId, $types);
        dump($fds, $data);
        $this->sendFdsMessage($fds->toArray(), json_encode([
            'event' => $event,
            'data' => $data,
        ]));
    }

    public function sendUserMessage($userId, $message)
    {
        $fds = $this->getFds($userId, 1);
        $this->sendFdsMessage($fds, $message);
    }


    public function sendFdsMessage($fds, $message)
    {
        if (!is_array($fds)) {
            $fds = [$fds];
        }
        $server = di()->get(ServerFactory::class)->getServer()->getServer();
        foreach ($fds as $fd) {
            $exists = $server->exist(intval($fd));
            $exists && $server->push(intval($fd), $message);
        }
    }

}